#include "dequeue.hpp"
#include <iostream>
#include <vector>
#include <thread>
#include <unordered_map>
#include <functional>
#include <cassert>
#include "functional.hpp"
using namespace std;

// // 测试函数
// void testDeQueue() {
//     const int QUEUE_SIZE = 16777216;
//     const int NUM_THREADS = 8;
//     const int NUM_OPS = 10000;

//     DeQueue queue(QUEUE_SIZE);
//     std::vector<std::thread> threads;
//     std::atomic<int> total_pushed(0);
//     std::atomic<int> total_popped(0);

//     // 入队线程函数
//     auto enqueue_func = [&]() {
//         for (int i = 0; i < NUM_OPS; ++i)
//         {
//             if (queue.push(i))
//             {
//                 total_pushed.fetch_add(1, std::memory_order_relaxed);
//             }
//         }
//     };

//     // 出队线程函数
//     auto dequeue_func = [&]()
//     {
//         for (int i = 0; i < NUM_OPS; ++i)
//          {
//             int val = queue.pop();
//             if (val != -1) {
//                 total_popped.fetch_add(1, std::memory_order_relaxed);
//             }
//         }
//     };

//     // 创建入队和出队线程
//     for (int i = 0; i < NUM_THREADS / 2; ++i)
//     {
//         threads.emplace_back(enqueue_func);
//         threads.emplace_back(dequeue_func);
//     }

//     // 等待所有线程完成
//     for (auto& t : threads)
//     {
//         t.join();
//     }

//     // 检查队列状态
//     std::cout << "Total pushed: " << total_pushed.load() << std::endl;
//     std::cout << "Total popped: " << total_popped.load() << std::endl;
//     assert(total_popped.load() <= total_pushed.load());

//     std::cout << "Test passed!" << std::endl;
// }

// int main()
// {
//     testDeQueue();
//     return 0;
// }

int main()
{

    vector<thread> threads;
    size_t q_size = 1000;
    int threadcount = 8, insertcount = 10000000;

#ifdef FUNCTION
    DeQueue<Functional<int(int, int)>> dq(q_size);
#else
    auto ff = [](int x, int y)
    { return x + y; };
    using type = std::function<int(int, int)>;
    DeQueue<type> dq(q_size);
#endif

    for (int i = 0; i < threadcount; i++)
    {
        threads.emplace_back([&]()
                             {
                        for (int i = 0; i < insertcount; i++)
                        {

                            #ifdef FUNCTION
                                auto f1 = [](int x, int y)
                                { return x + y; };
                                Functional<int(int, int)> f(f1);
                            #else 
                            auto f = std::bind(ff, std::placeholders::_1, std::placeholders::_2);
                            #endif


                            dq.push(std::move(f));
                        } });
    }

    for (int i = 0; i < threadcount; i++)
    {
        threads[i].join();
    }

    // unordered_map<int, int> hash;
    // int val = 0;
    // while ((val = dq.pop()) != -1)
    // {
    //      hash[val]++;
    // }

    // for (auto e : hash)
    // {
    //      if (e.second != threadcount)
    //      {
    //              cout << "线程不安全" << endl;
    //              return 0;
    //      }
    // }

    // cout << "线程安全" << endl;
    return 0;
}